Skip to main content

OpenSSH

OpenSSH is the standard open-source implementation of the SSH protocol used for secure remote login, file transfers, and remote command execution over untrusted networks. It provides the sshd server (to accept connections) and client tools such as ssh, scp, and sftp. For VPS and WordPress server operations, OpenSSH is the primary remote administration channel and must be configured carefully to reduce brute-force risk and prevent lockouts.

Background and history

SSH was created to replace insecure remote access tools (such as Telnet and rsh) by providing encryption, authentication, and integrity protection. OpenSSH emerged as a widely adopted open-source implementation and became the default SSH stack on most Linux distributions. Over time, OpenSSH added stronger cryptography defaults, better key types (such as Ed25519), and more configuration controls for modern hardening baselines.

Adoption and where it’s commonly used

OpenSSH is used across:

  • Linux servers (Ubuntu/Debian, RHEL-based, Alpine)
  • Cloud/VPS fleets for remote administration
  • CI/CD and automation (key-based access, forced commands)
  • Secure file transfer workflows (SFTP)

Maintained by

  • Maintained by the OpenSSH project community.

Best when to use

  • You need secure remote shell access to servers.
  • You need secure file transfer (SFTP) without opening additional services.
  • You need controlled remote administration with keys, restricted users, and auditing.
  • You want a widely supported protocol and tooling for automation.

Not suitable when

  • You need browser-based or zero-trust access without inbound ports exposed (use a bastion/overlay access model).
  • You cannot safely expose SSH to the internet and lack firewalling or access control.
  • You need centralized enterprise access governance that mandates different tooling.

Compatibility notes

  • Linux distributions typically ship OpenSSH by default, but versions differ.

  • Service name differs by distro:

    • Debian/Ubuntu: ssh
    • RHEL/Fedora/Rocky/AlmaLinux: sshd
  • Configuration file locations:

    • Server: /etc/ssh/sshd_config and often /etc/ssh/sshd_config.d/*.conf
    • Client: /etc/ssh/ssh_config and ~/.ssh/config
  • Logs differ by distro:

    • Debian/Ubuntu: /var/log/auth.log
    • RHEL-based: /var/log/secure
  • Some environments use upstream firewalls (cloud security groups) in addition to host firewalls.

Lockout risk

Changes to sshd configuration can lock you out immediately after a reload/restart. Keep an existing SSH session open, validate config with sshd -t, test in a second session, and ensure firewall rules allow your access path before applying changes.

Concepts and how it works

OpenSSH uses a client-server model:

  • The server daemon sshd listens on a TCP port (default 22) and enforces authentication and access policies.
  • The client ssh negotiates encryption, authenticates (preferably using keys), then opens a session or executes a command.

Installation

Debian/Ubuntu

sudo apt update
sudo apt install openssh-server openssh-client

RHEL/CentOS Stream/Rocky/AlmaLinux/Fedora

sudo dnf install openssh-server openssh-clients

Alpine

sudo apk add openssh

Enable and start the server (if not already enabled):

sudo systemctl enable --now ssh 2>/dev/null || sudo systemctl enable --now sshd

Core components

ComponentPurpose
--
sshdSSH server daemon
sshSSH client
sftpSecure file transfer client
scpSecure copy (legacy; use SFTP where feasible)
ssh-keygenGenerate and manage keys
ssh-agent / ssh-addKey caching for client sessions
authorized_keysServer-side list of permitted public keys

Common commands (daily operations)

Connect to a server

ssh user@server_ip

Custom port:

ssh -p 2581 user@server_ip

Use a specific key:

ssh -i ~/.ssh/id_ed25519 user@server_ip

Copy a file (prefer SFTP in modern workflows)

SFTP interactive session:

sftp -P 2581 user@server_ip

Non-interactive upload example:

sftp -P 2581 user@server_ip <<'EOF'
put ./local-file /tmp/local-file
EOF

Run a remote command

ssh -p 2581 user@server_ip "uname -a && uptime"

Key-based authentication

Key-based authentication is the standard for secure SSH.

ssh-keygen -t ed25519 -a 64 -f ~/.ssh/id_ed25519

Install the public key on the server

ssh-copy-id -p 2581 user@server_ip

Or manually append to the server:

mkdir -p ~/.ssh
chmod 700 ~/.ssh
cat >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Server configuration basics (sshd_config)

Validate config before applying

sudo sshd -t

Inspect effective runtime configuration

sudo sshd -T | head

Common hardening settings

Prefer drop-in files in /etc/ssh/sshd_config.d/ when available.

Example drop-in: /etc/ssh/sshd_config.d/10-hardening.conf

# Prefer key auth
PasswordAuthentication no
KbdInteractiveAuthentication no

# Disable direct root login
PermitRootLogin no

# Limit who can log in
AllowUsers admin ops

# Reduce noise (optional)
MaxAuthTries 3
LoginGraceTime 30

Apply safely:

sudo sshd -t
sudo systemctl reload ssh 2>/dev/null || sudo systemctl reload sshd
PasswordAuthentication changes

Disabling password authentication requires that at least one working public key is installed and tested for your admin user. Confirm access in a second session before closing the original session.

Port management

Check what port SSH is listening on

sudo ss -tulpen | grep sshd

Change SSH port safely (summary)

  1. Allow new port in firewall and provider security group.
  2. Set Port <new_port> (drop-in preferred).
  3. Validate: sudo sshd -t
  4. Reload SSH.
  5. Confirm listener: sudo ss -tulpen | grep <new_port>
  6. Test new login in a second session.
  7. Optionally close port 22 after confirmation.

SSH forwarding and tunnels

Local port forward (common for admin access to internal services)

Example: expose remote MySQL locally (only when access controls are appropriate):

ssh -L 3307:127.0.0.1:3306 -p 2581 user@server_ip

Then connect locally to 127.0.0.1:3307.

Exposing sensitive services

Port forwarding can bypass network segmentation and firewall intent. Use it only for controlled admin workflows, bind to localhost, and close tunnels when done.

Logging and auditing

View SSH authentication logs

Debian/Ubuntu:

sudo tail -n 200 /var/log/auth.log

RHEL-based:

sudo tail -n 200 /var/log/secure

Systemd journal (portable):

sudo journalctl -u ssh -n 200 --no-pager 2>/dev/null || sudo journalctl -u sshd -n 200 --no-pager

Troubleshooting

Cannot connect (timeout)

Likely causes:

  • Firewall/security group blocks the port
  • Wrong IP (IPv4 vs IPv6)
  • sshd not listening or service down

Checks on the server (console access if SSH is unavailable):

sudo ss -tulpen | grep sshd || true
sudo systemctl status ssh 2>/dev/null || sudo systemctl status sshd

Connection refused

Likely causes:

  • sshd not listening on that port
  • Service not running
  • Connecting to the wrong port

Check effective ports:

sudo sshd -T | grep -i '^port '

Authentication failure

Likely causes:

  • Wrong username
  • Key not installed or wrong key used
  • Permissions on ~/.ssh incorrect
  • AllowUsers/AllowGroups restrictions

Server-side checks:

id <user>
sudo ls -ld /home/<user> /home/<user>/.ssh 2>/dev/null || true
sudo ls -l /home/<user>/.ssh/authorized_keys 2>/dev/null || true
sudo sshd -T | grep -E '^(allowusers|allowgroups|passwordauthentication|permitrootlogin)'

sshd reload fails

Validate and inspect logs:

sudo sshd -t
sudo journalctl -u ssh -n 200 --no-pager 2>/dev/null || sudo journalctl -u sshd -n 200 --no-pager

Security notes

  • Prefer Ed25519 keys and protect private keys with passphrases.
  • Disable password authentication where feasible.
  • Disable direct root SSH login; use a sudo-capable admin user.
  • Restrict SSH access by IP (firewall allowlist) when possible.
  • Use rate limiting / banning (for example Fail2Ban) to reduce brute-force impact.
  • Keep OpenSSH updated as part of regular patching.

Quick reference

GoalCommand
---
Install (Ubuntu/Debian)sudo apt install openssh-server openssh-client
Service statussystemctl status ssh || systemctl status sshd
Validate configsudo sshd -t
Show effective configsudo sshd -T
Check listening portssudo ss -tulpen | grep sshd
Connectssh user@host
Connect custom portssh -p 2581 user@host
Copy keyssh-copy-id -p 2581 user@host
View logsjournalctl -u ssh -n 200 --no-pager || journalctl -u sshd -n 200 --no-pager